import React, { useState, useEffect, useRef } from "react";
import { Modal, Slider, Button, message } from "antd";
import { AudioMutedOutlined, SoundOutlined, CloseOutlined, PhoneOutlined } from "@ant-design/icons";
import "./index.css";
import { useSelector } from "react-redux";
import socketInstance from "@/api/socket";
import { MessageType } from "@/api/type/messageType";
import CallSoundManager from "@/util/callSound";

interface VoiceCallProps {
  visible: boolean;
  onClose: () => void;
  friendId: number;
  friendName: string;
  friendAvatar: string;
  isIncoming?: boolean;
}

const VoiceCall: React.FC<VoiceCallProps> = ({
  visible,
  onClose,
  friendId,
  friendName,
  friendAvatar,
  isIncoming = false
}) => {
  const [isMuted, setIsMuted] = useState(false);
  const [volume, setVolume] = useState(50);
  const [callStatus, setCallStatus] = useState<"calling" | "connected" | "failed" | "waiting">
    (isIncoming ? "waiting" : "calling");
  const localAudioRef = useRef<HTMLAudioElement>(null);
  const remoteAudioRef = useRef<HTMLAudioElement>(null);
  const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
  const localStreamRef = useRef<MediaStream | null>(null);
  const userInfo = useSelector((state: any) => state.user.userinfo);

  // 初始化WebRTC连接
  useEffect(() => {
    if (visible) {
      // 来电时播放铃声
      if (isIncoming) {
        CallSoundManager.getInstance().playRingtone();
      }
      initCall();
    }
    
    return () => {
      handleHangup();
    };
  }, [visible]);

  // 监听音量变化
  useEffect(() => {
    if (remoteAudioRef.current) {
      remoteAudioRef.current.volume = volume / 100;
    }
  }, [volume]);

  // 监听通话状态变化
  useEffect(() => {
    // 通话连接时
    if (callStatus === "connected") {
      // 停止铃声播放
      CallSoundManager.getInstance().stopRingtone();
      // 播放连接音效
      CallSoundManager.getInstance().playConnectSound();
    }
    
    // 通话失败时
    if (callStatus === "failed") {
      // 停止铃声播放
      CallSoundManager.getInstance().stopRingtone();
      // 播放结束音效
      CallSoundManager.getInstance().playEndSound();
    }
  }, [callStatus]);

  // 创建WebRTC连接
  const initCall = async () => {
    try {
      // 获取本地音频流
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
      localStreamRef.current = stream;
      
      if (localAudioRef.current) {
        localAudioRef.current.srcObject = stream;
      }

      // 创建对等连接
      const peerConnection = new RTCPeerConnection({
        iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
      });
      peerConnectionRef.current = peerConnection;

      // 添加本地音频轨道到连接
      stream.getAudioTracks().forEach(track => {
        if (peerConnectionRef.current) {
          peerConnectionRef.current.addTrack(track, stream);
        }
      });

      // 监听远程流
      peerConnection.ontrack = (event) => {
        if (remoteAudioRef.current) {
          remoteAudioRef.current.srcObject = event.streams[0];
          setCallStatus("connected");
        }
      };

      // 监听ICE连接状态
      peerConnection.oniceconnectionstatechange = () => {
        if (peerConnection.iceConnectionState === "failed" || 
            peerConnection.iceConnectionState === "disconnected") {
          setCallStatus("failed");
          message.error("通话连接失败，可能是网络问题");
        }
      };

      const socket = socketInstance.socket;
      if (!socket) {
        throw new Error("Socket连接不可用，请刷新页面后重试");
      }

      // 监听通话错误
      socket.on("callError", (errorData) => {
        console.error("通话错误:", errorData);
        message.error(errorData.message || "通话请求失败");
        setCallStatus("failed");
        // 停止铃声
        CallSoundManager.getInstance().stopRingtone();
        // 延迟关闭对话框，让用户看到错误信息
        setTimeout(() => {
          onClose();
        }, 2000);
      });

      // 监听通话被拒绝
      socket.on(MessageType.VOICECALL_REJECT, (data) => {
        if (data.from === friendId) {
          message.info("对方拒绝了通话");
          setCallStatus("failed");
          setTimeout(() => {
            onClose();
          }, 2000);
        }
      });

      // 监听通话被接受
      socket.on(MessageType.VOICECALL_ACCEPT, async (data) => {
        if (data.from === friendId && !isIncoming) {
          message.success("对方已接受通话");
          
          // 创建并发送offer
          try {
            if (peerConnectionRef.current) {
              const offer = await peerConnectionRef.current.createOffer();
              await peerConnectionRef.current.setLocalDescription(offer);
              
              // 发送offer给对方
              socket.emit(MessageType.VOICECALL_OFFER, {
                to: friendId,
                from: userInfo.id,
                offer: peerConnectionRef.current.localDescription
              });
            }
          } catch (error) {
            console.error("创建offer失败:", error);
            message.error("建立通话连接时出错");
            setCallStatus("failed");
          }
        }
      });

      // 监听ICE候选
      peerConnection.onicecandidate = (event) => {
        if (event.candidate && socket) {
          // 发送ICE候选到对方
          socket.emit(MessageType.VOICECALL_ICE, {
            to: friendId,
            from: userInfo.id,
            candidate: event.candidate
          });
        }
      };

      // 如果是来电，不要自动创建offer，等待用户接受
      if (!isIncoming) {
        // 发送通话请求，等待对方接受
        socket.emit(MessageType.VOICECALL_REQUEST, {
          to: friendId,
          from: userInfo.id,
          username: userInfo.userName
        });
      }

      // 监听offer
      socket.on(MessageType.VOICECALL_OFFER, async (data) => {
        if (data.from === friendId && peerConnectionRef.current) {
          try {
            await peerConnectionRef.current.setRemoteDescription(new RTCSessionDescription(data.offer));
            
            // 创建并发送answer
            const answer = await peerConnectionRef.current.createAnswer();
            await peerConnectionRef.current.setLocalDescription(answer);
            
            socket.emit(MessageType.VOICECALL_ANSWER, {
              to: friendId,
              from: userInfo.id,
              answer: peerConnectionRef.current.localDescription
            });
          } catch (error) {
            console.error("处理offer失败:", error);
            message.error("建立通话连接时出错");
            setCallStatus("failed");
          }
        }
      });

      // 监听answer
      socket.on(MessageType.VOICECALL_ANSWER, async (data) => {
        if (data.from === friendId && peerConnectionRef.current) {
          try {
            await peerConnectionRef.current.setRemoteDescription(new RTCSessionDescription(data.answer));
          } catch (error) {
            console.error("处理answer失败:", error);
            message.error("建立通话连接时出错");
            setCallStatus("failed");
          }
        }
      });

      // 监听ICE候选
      socket.on(MessageType.VOICECALL_ICE, async (data) => {
        if (data.from === friendId && peerConnectionRef.current) {
          try {
            await peerConnectionRef.current.addIceCandidate(new RTCIceCandidate(data.candidate));
          } catch (error) {
            console.error("添加ICE候选失败:", error);
            // 不显示错误，因为ICE候选有可能失败，这是正常的
          }
        }
      });

      // 监听挂断
      socket.on(MessageType.VOICECALL_HANGUP, (data) => {
        if (data.from === friendId) {
          message.info("对方已挂断");
          // 播放结束音效
          CallSoundManager.getInstance().playEndSound();
          
          // 通话已结束，执行关闭操作，但不再发送挂断信号
          // 因为是收到对方挂断的通知，自己不需要再发送挂断
          setCallStatus("failed");
          closeCallWithoutSignaling();
        }
      });

    } catch (error) {
      console.error("初始化通话失败:", error);
      setCallStatus("failed");
      
      // 提供更具体的错误信息
      if (error instanceof Error) {
        if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") {
          message.error("麦克风权限被拒绝，请允许浏览器访问麦克风");
        } else if (error.name === "NotFoundError" || error.name === "DevicesNotFoundError") {
          message.error("未检测到麦克风设备，请确认麦克风已连接");
        } else if (error.name === "NotReadableError" || error.name === "TrackStartError") {
          message.error("麦克风被其他应用占用，请关闭其他使用麦克风的应用");
        } else if (error.message.includes("Socket")) {
          message.error(error.message);
        } else {
          message.error("无法初始化通话，请检查网络和设备");
        }
      } else {
        message.error("无法初始化通话，请检查网络和设备");
      }
    }
  };

  // 静音切换
  const toggleMute = () => {
    if (localStreamRef.current) {
      const audioTracks = localStreamRef.current.getAudioTracks();
      audioTracks.forEach(track => {
        track.enabled = !track.enabled;
      });
      setIsMuted(!isMuted);
    }
  };

  // 接受通话
  const acceptCall = () => {
    const socket = socketInstance.socket;
    if (socket) {
      socket.emit(MessageType.VOICECALL_ACCEPT, {
        to: friendId,
        from: userInfo.id
      });
      setCallStatus("calling");
      // 停止铃声
      CallSoundManager.getInstance().stopRingtone();
    }
  };

  // 拒绝通话
  const rejectCall = () => {
    const socket = socketInstance.socket;
    if (socket) {
      socket.emit(MessageType.VOICECALL_REJECT, {
        to: friendId,
        from: userInfo.id
      });
      // 停止铃声
      CallSoundManager.getInstance().stopRingtone();
      // 播放拒绝音效
      CallSoundManager.getInstance().playEndSound();
      onClose();
    }
  };

  // 挂断通话
  const handleHangup = () => {
    const socket = socketInstance.socket;
    if (socket) {
      // 通知对方已挂断
      socket.emit(MessageType.VOICECALL_HANGUP, {
        to: friendId,
        from: userInfo.id
      });
    }

    // 播放挂断音效
    CallSoundManager.getInstance().playEndSound();
    
    // 停止铃声
    CallSoundManager.getInstance().stopRingtone();

    // 清理资源并关闭通话界面
    closeCall();
  };
  
  // 关闭通话但不发送挂断信号
  const closeCallWithoutSignaling = () => {
    const socket = socketInstance.socket;
    if (socket) {
      // 移除事件监听
      socket.off(MessageType.VOICECALL_OFFER);
      socket.off(MessageType.VOICECALL_ANSWER);
      socket.off(MessageType.VOICECALL_ICE);
      socket.off(MessageType.VOICECALL_HANGUP);
      socket.off(MessageType.VOICECALL_ACCEPT);
      socket.off(MessageType.VOICECALL_REJECT);
      socket.off("callError");
    }
    
    // 清理资源
    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach(track => track.stop());
    }

    if (peerConnectionRef.current) {
      peerConnectionRef.current.close();
      peerConnectionRef.current = null;
    }

    onClose();
  };
  
  // 完全关闭通话（包括清理资源和发送挂断信号）
  const closeCall = () => {
    const socket = socketInstance.socket;
    if (socket) {
      // 移除事件监听
      socket.off(MessageType.VOICECALL_OFFER);
      socket.off(MessageType.VOICECALL_ANSWER);
      socket.off(MessageType.VOICECALL_ICE);
      socket.off(MessageType.VOICECALL_HANGUP);
      socket.off(MessageType.VOICECALL_ACCEPT);
      socket.off(MessageType.VOICECALL_REJECT);
      socket.off("callError");
    }
    
    // 清理资源
    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach(track => track.stop());
    }

    if (peerConnectionRef.current) {
      peerConnectionRef.current.close();
      peerConnectionRef.current = null;
    }

    onClose();
  };

  return (
    <Modal
      title="语音通话"
      open={visible}
      footer={null}
      closable={false}
      centered
      className="voice-call-modal"
      maskClosable={false}
    >
      <div className="voice-call-container">
        <div className="user-info">
          <img src={friendAvatar} alt={friendName} className="avatar" />
          <h3>{friendName}</h3>
          <p>
            {callStatus === "waiting" 
              ? `${friendName} 邀请您通话` 
              : callStatus === "calling" 
                ? "正在呼叫..." 
                : callStatus === "connected" 
                  ? "通话中" 
                  : "通话失败"}
          </p>
        </div>

        {callStatus === "waiting" ? (
          <div className="call-controls">
            <Button
              type="primary"
              shape="circle"
              icon={<PhoneOutlined />}
              onClick={acceptCall}
              className="control-button accept-button"
              style={{ backgroundColor: "#52c41a", borderColor: "#52c41a" }}
            />
            
            <Button
              danger
              shape="circle"
              icon={<CloseOutlined />}
              onClick={rejectCall}
              className="control-button reject-button"
            />
          </div>
        ) : (
          <>
            <div className="call-controls">
              <Button
                type="primary"
                shape="circle"
                icon={isMuted ? <AudioMutedOutlined /> : <SoundOutlined />}
                onClick={toggleMute}
                className="control-button"
              />
              
              <Button
                danger
                shape="circle"
                icon={<CloseOutlined />}
                onClick={handleHangup}
                className="control-button hangup-button"
              />
            </div>

            <div className="volume-control">
              <SoundOutlined />
              <Slider
                value={volume}
                onChange={setVolume}
                className="volume-slider"
              />
            </div>
          </>
        )}

        {/* 音频元素（隐藏） */}
        <audio ref={localAudioRef} autoPlay muted style={{ display: "none" }} />
        <audio ref={remoteAudioRef} autoPlay style={{ display: "none" }} />
      </div>
    </Modal>
  );
};

export default VoiceCall; 